#include "../../StdInc.h"

#ifdef BUILD_LTS

#include <boost/format.hpp>

#include "LTSMarketDataApi.h"
#include "LTSMarketDataSpiImpl.h"


namespace GSTrader
{
	namespace TradeService
	{
		CLtsMarketDataApi::CLtsMarketDataApi() : CMarketDataApi(ptLts)
		{
			m_pMarketDataApi = NULL;
			m_pSpiImpl = NULL;
		}

		CLtsMarketDataApi::~CLtsMarketDataApi()
		{
			_delete(m_pSpiImpl)
		}

		string CLtsMarketDataApi::GetKey()
		{
			if (m_pConnectionInfo && m_pConnectionInfo->m_pBroker)
			{
				boost::format f("%1%_%2%_%3%");
				f % m_pConnectionInfo->m_pBroker->m_nPlatformType;
				f % m_pConnectionInfo->m_pBroker->m_strBrokerID;
				f % m_nProviderId;
				return f.str();
			}

			return "";
		}

		void CLtsMarketDataApi::AddMarketDataMsg(CMsg* pMsg)
		{
			if (m_pMarketDataQueue == NULL)
				return;

			m_pMarketDataQueue->Push(pMsg);
		}

		int CLtsMarketDataApi::Init(MarketDataApiConnParam& param)
		{
			CConnectionInfo* pUser = param.m_pConnectionInfo;
			if (pUser == NULL || pUser->m_pBroker == NULL)
			{
				assert(false);
				return -1;
			}

			m_pConnectionInfo = pUser;

			string strPath = "log\\md\\";
			strPath += pUser->m_strInvestorID;
			if (!Util::CFileSystem::CreateCurrentSubDir(strPath))
			{
				assert(false);
				return -1;
			}

			m_pMarketDataApi = CSecurityFtdcMdApi::CreateFtdcMdApi(strPath.c_str());
			m_pSpiImpl = new CLtsMarketDataSpiImpl(this);
			m_pMarketDataApi->RegisterSpi((CSecurityFtdcMdSpi*)m_pSpiImpl);

			for (size_t x = 0; x < pUser->m_pBroker->m_vQuoteFront.size(); x++)
			{
				m_pMarketDataApi->RegisterFront((char*)pUser->m_pBroker->m_vQuoteFront[x].c_str());
			}

			m_pMarketDataApi->Init();
			m_pMarketDataQueue = param.m_pMarketDataQueue;

			return 0;
		}

		void CLtsMarketDataApi::Destory()
		{
			m_pMarketDataApi->RegisterSpi(NULL);
			m_pMarketDataApi->Release();
			m_pMarketDataApi = NULL;
			_delete(m_pSpiImpl)
		}

		int CLtsMarketDataApi::ReqUserLogin()
		{
			CSecurityFtdcReqUserLoginField req;
			memset(&req, 0, sizeof(req));

			memcpy(req.BrokerID, m_pConnectionInfo->m_pBroker->m_strBrokerID.c_str(), sizeof(req.BrokerID));
			memcpy(req.UserID,	 m_pConnectionInfo->m_strInvestorID.c_str(), sizeof(req.UserID));
			memcpy(req.Password, m_pConnectionInfo->m_strUserPassWord.c_str(), sizeof(req.Password));

			int iResult = m_pMarketDataApi->ReqUserLogin(&req, m_lRequestID++);
			return iResult;
		}

		int CLtsMarketDataApi::RegUserLogOut()
		{
			CSecurityFtdcUserLogoutField req;
			memset(&req, 0, sizeof(req));

			memcpy(req.BrokerID, m_pConnectionInfo->m_pBroker->m_strBrokerID.c_str(), sizeof(req.BrokerID));
			memcpy(req.UserID, m_pConnectionInfo->m_strInvestorID.c_str(), sizeof(req.UserID));

			int iResult = m_pMarketDataApi->ReqUserLogout(&req, m_lRequestID++);
			return iResult;
		}

		bool CLtsMarketDataApi::Subscribe(CSubscribeInstrument* pSubscribe)
		{
			if (pSubscribe == NULL)
				return false;

			map<string, vector<string>>& mapIns = pSubscribe->m_mapInstrument;
			for (auto it : mapIns)
			{
				SubscribeMarketData(it.second, it.first);
			}
			/*
			pSubscribe->m_mapInstrument::iterator it;
			for (it = pSubscribe->m_mapInstrument.begin(); it != pSubscribe->m_mapInstrument.end(); it++)
			{
				SubscribeMarketData(it.second, it.first);
			}
			*/

			return true;
		}

		bool CLtsMarketDataApi::SubscribeMarketData(vector<string>& arrInstrument)
		{

			return false;
		}

		bool CLtsMarketDataApi::UnSubscribeMarketData(vector<string>& arrInstrument)
		{
			return false;
		}

		bool CLtsMarketDataApi::SubscribeMarketData(vector<string>& arrInstrument, string strExchangeID)
		{
			size_t iInstrumentID = arrInstrument.size();
			if (iInstrumentID == 0)
			{
				return false;
			}

			char** pInstrumentID = new char* [iInstrumentID];

			size_t i;
			for (i = 0; i < iInstrumentID; i++)
			{
				pInstrumentID[i] = new char[20];
				memcpy(pInstrumentID[i], arrInstrument[i].c_str(), 20);
			}

			int iResult = m_pMarketDataApi->SubscribeMarketData(pInstrumentID, iInstrumentID, (char*)strExchangeID.c_str());

			for (i = 0; i < iInstrumentID; i++)
			{
				_delete(pInstrumentID[i])
			}

			_delarr(pInstrumentID)
			return true;
		}

		bool CLtsMarketDataApi::UnSubscribeMarketData(vector<string>& arrInstrument, string strExchangeID)
		{
			size_t iInstrumentID = arrInstrument.size();
			if (iInstrumentID == 0)
			{
				return false;
			}

			char** pInstrumentID = new char* [iInstrumentID];

			size_t i;
			for (i = 0; i < iInstrumentID; i++)
			{
				pInstrumentID[i] = new char[20];
				memcpy(pInstrumentID[i], arrInstrument[i].c_str(), 20);
			}

			int iResult = m_pMarketDataApi->UnSubscribeMarketData(pInstrumentID, iInstrumentID, (char*)strExchangeID.c_str());

			for (i = 0; i < iInstrumentID; i++)
			{
				_delete(pInstrumentID[i])
			}

			_delarr(pInstrumentID)

			return true;
		}

	}
}

#endif